package core;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.security.NoSuchAlgorithmException;
import java.util.Date;

import org.junit.BeforeClass;
import org.junit.Test;

public class PostTest {
	static final String TEST_URL =
		"http://www.informatica64.com/dust/elladodelmal.xml";
	static Blog blog;
	static Post test_post;
	
	@BeforeClass  	
	public static void setUpClass() throws Exception {
		// Abusing a bit, let's use blog to take (in an easy way) a post.
		blog = new Blog(new URL(TEST_URL), "Awesomest channel's name ever");
		blog.update();
		test_post = blog.getPost(1);
	}
	
	@Test
	public void testLoadImages() {
		int n_images_loaded;
		
		// Correct case with images being loaded.
		try {
			n_images_loaded = test_post.loadImages();
			assertEquals(10, n_images_loaded);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		// Correct case with images don't being loaded (since we have already
		// loaded them above).
		try {
			n_images_loaded = test_post.loadImages();
			assertEquals(10, n_images_loaded);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		// Incorrect case, bad-formed img src attribute value.
		try {
			Date date = new Date();
			String title = "Test title";
			URL http_url = new URL("http://non-existant.domain/post");
			String author = "Test author";
			String content = "<img src=\"folder/image.png\">";
			Post post = new Post(date, title, http_url, author, content);
			
			post.loadImages();
			fail("testLoadImages must throw and exception");
		}
		catch (Exception e) {}
		
		// Incorrect case, well-formed but unexistant image.
		try {
			Date date = new Date();
			String title = "Test title";
			URL http_url = new URL("http://non-existant.domain/post");
			String author = "Test author";
			String content = "<img src=\"./folder/image.png\">";
			Post post = new Post(date, title, http_url, author, content);
			
			post.loadImages();
			fail("testLoadImages must throw and exception");
		}
		catch (Exception e) {}
	}
	
	@Test
	public void testMangleAlts() throws NoSuchAlgorithmException, IOException {
		String returned_content;
		Post post_mangled, post_images_not_loaded;
		Date date = new Date();
		String title = "Test title";
		URL url = new URL("http://non-existant.domain/post");
		String author = "Test author";
		String content;
		File fd;
		FileInputStream fis;
		int len;
		
		fd = new File("tests_post/post_mangled.html");
		fis = new FileInputStream(fd);
		len = (int)fd.length();
		content = new String(Util.recoverDatafromInputStream(fis, len));
		
		post_mangled = new Post(date, title, url, author, content);
		test_post.loadImages();
		
		// Correct case, mangle the alt attribute values of a whole real post.
		// NOTE: This method will fail if you change the post choosen to do the
		// tests. Also if new P2P networks are supported since they would
		// appear in the alt attributes. If you do so, you have to rewrite the
		// "post_mangled.html" file with the new content.
		try {
			returned_content = test_post.mangleAlts();
			assertEquals(returned_content, post_mangled.getContent());
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		// Incorrect case, images weren't loaded.
		post_images_not_loaded = new Post(date, title, url, author, content);
		try {
			post_images_not_loaded.mangleAlts();
			fail("testMangleAlts should thrown an exception.");
		}
		catch (Exception e) {}
	}
	
	@Test
	public void testSave2File() {
		File fd;
		
		// Correct case, save the post to a file.
		try {
			test_post.save2File("tests_post/longnametoavoidcollitionswithanotherpost.html");
			
			fd = new File("tests_post/longnametoavoidcollitionswithanotherpost.html");
			if (!fd.delete())
				System.out.println("[WARN]: cannot delete test file.");
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testCreateZip() {
		File fd;
		
		// Correct case, the post is zipped.
		try {
			test_post.createZip("tests_post", "longnametoavoidcollitionswithanotherzip");
			
			fd = new File("tests_post/longnametoavoidcollitionswithanotherzip.zip");
			if (!fd.delete())
				System.out.println("[WARN]: cannot delete test zip file.");
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testGetDate() {
		String date = "Tue Jan 25 08:35:00 CET 2011";
		Date post_date = test_post.getDate();
		assertEquals(post_date.toString(), date);
	}
	
	@Test
	public void testGetTitle() {
		String title = "Entrevista a Lorenzo de SecurityByDefault";
		String post_title = test_post.getTitle();
		assertEquals(post_title, title);
	}
	
	@Test
	public void testGetAuthor() {
		String author = "noreply@blogger.com (Maligno)";
		String post_author = test_post.getAuthor();
		assertEquals(post_author, author);
	}
	
	@Test
	public void testGetContent() throws FileNotFoundException {
		File fd;
		FileInputStream fis;
		String content, post_content;
		int len;
		
		fd = new File("tests_post/post_content.html");
		fis = new FileInputStream(fd);
		len = (int)fd.length();
		content = new String(Util.recoverDatafromInputStream(fis, len));
		
		post_content = test_post.getContent();
		assertEquals(post_content, content);
	}
	
	@Test
	public void testGetUrl() {
		String url = "http://feedproxy.google.com/~r/ElLadoDelMal/~3/PJJbaQ0rYkE/entrevista-lorenzo-de-securitybydefault.html";
		URL post_url = test_post.getUrl();
		assertEquals(post_url.toString(), url);
	}
	
	@Test
	public void testGetImages() throws NoSuchAlgorithmException, IOException {
		int n_images = 10;
		int post_n_images;
		
		test_post.loadImages();
		
		// Correct case.
		try {
			post_n_images = test_post.getImages().size();
			assertEquals(n_images, post_n_images);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		// Incorrect case, loadImages() haven't been called.
		try {
			Date date = new Date();
			String title = "Test title";
			URL http_url = new URL("http://non-existant.domain/post");
			String author = "Test author";
			String content = "Test content";
			Post post = new Post(date, title, http_url, author, content);
			
			post_n_images = post.getImages().size();
			fail("testGetImages should thrown an exception");
		}
		catch (Exception e) {}
	}
	
	@Test
	public void testSetTitle() {
		String new_title = "New test title";
		
		test_post.setTitle(new_title);
		assertEquals(test_post.getTitle(), new_title);
	}
	
	@Test
	public void testMarkAsReadedAndHasBeenReaded() {
		if (test_post.hasBeenRead())
			fail("Post is marked as readed and it shouldn't");
		
		test_post.markAsRead();
		if (!test_post.hasBeenRead())
			fail("Post has been marked as readed and it says no.");
	}
}
